﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Counter1
{
    /// <summary>
    /// 检验表达式的合法性
    /// </summary>
    class Inspect
    {
        //可变字符串
        readonly StringBuilder newstr = new StringBuilder();

        //可变字符串长度
        private int length = 0;

        //存储字符串表达式
        private string equation;

        //错误提示
        public string errors = "";

        //操作符栈
        private readonly Stack<char> optrStack = new Stack<char>();

        //统计操作符个数
        private int optr = 0;

        //统计运算数个数
        private int opnd = 0;

        public Inspect (string str)
        {
            newstr.Append(str);
            length = newstr.Length;
            equation = newstr.ToString();
        }

        /// <summary>
        /// 检验表达式是否有误、优化表达式
        /// </summary>
        /// <returns>优化后的表达式</returns>
        public string Iswrong()
        {
            //剔除空格
            Delspace();

            //检验未完成输入的表达式
            Incomplete();

            //检查连续操作符
            Seriesoptr();

            //检查空括号
            Emptybrackets();

            //检验未知字符
            Undefined();

            //检验括号匹配
            Pairbrackets();

            //检验乘法缩写
            Shortening();

            //检验负数
            Negative();

            return equation;
        }

        /// <summary>
        /// 剔除空格
        /// </summary>
        private void Delspace()
        {
            for (int i = 0; i < length; i++)
            {
                if (newstr[i] == ' ' || newstr[i] == '\t')
                {
                    newstr.Remove(i, 1);
                    length--;
                    i--;
                }
            }
            equation = newstr.ToString();
        }

        /// <summary>
        /// 检查连续操作符
        /// </summary>
        private void Seriesoptr()
        {
            for (int i = 0; i < length - 1; i++)
            {
                if (newstr[i] == '+' || newstr[i] == '-' || newstr[i] == '*' || newstr[i] == '/' || newstr[i] == '.')
                {
                    if (newstr[i + 1] == '+' || newstr[i + 1] == '-' || newstr[i + 1] == '*' || newstr[i + 1] == '/' || newstr[i + 1] == '.')
                    {
                        if (newstr[i] == newstr[i + 1])
                        {
                            newstr.Remove(i, 1);
                            length--;
                            i--;

                        }
                        else
                        {
                            errors += "\n[存在连续操作符: '" + newstr[i] + newstr[i + 1] + "'];";
                        }
                    }
                }
            }
            equation = newstr.ToString();
        }

        /// <summary>
        /// 检查空括号
        /// </summary>
        private void Emptybrackets()
        {
            for (int i = 0; i < length; i++)
            {
                if (newstr[i] == '(' && (i + 1) <length && newstr[i + 1] == ')')
                {
                    errors += "\n[存在空括号];";
                }
                else if (newstr[i] == ')' && (i + 1) < length && newstr[i + 1] == '(')
                {
                    errors += "\n[存在无效的括号: ')('];";
                }
            }
        }

        /// <summary>
        /// 检验未知字符
        /// </summary>
        private void Undefined()
        {
            foreach (var c in equation)
            {
                if (!char.IsDigit(c) && c != '.' && c != '+' && c != '-' && c != '*' && c != '/' && c != '(' && c != ')')
                {
                    errors += "\n[存在未知字符: '" + c + "'];";
                }
            }
        }

        /// <summary>
        /// 检验括号匹配
        /// </summary>
        private void Pairbrackets()
        {
            foreach (var c in equation)
            {
                if (c == '(')
                {
                    optrStack.Push(c);
                }
                else if (c == ')')
                {
                    if (optrStack.Count != 0)
                    {
                        optrStack.Pop();
                    }
                    else
                    {
                        errors += "\n[缺少左括号];";
                    }
                }
            }
            if(optrStack.Count != 0)
            {
                errors += "\n[缺少右括号];";
            }
        }

        /// <summary>
        /// 检验未完成输入的表达式
        /// </summary>
        private void Incomplete()
        {
            foreach(var c in equation)
            {
                if(char.IsDigit(c))
                {
                    opnd++;
                }
                else
                {
                    optr++;
                }
            }
            if(opnd == 0)
            {
                errors += "\n[未输入运算数];";
            }
            //else if(optr == 0)
            //{
            //    errors += "\n[未输入操作符];";
            //}
        }

        /// <summary>
        /// 检验乘法缩写
        /// </summary>
        private void Shortening()
        {
            for (int i = 0; i < length; i++)
            {
                if (char.IsDigit(newstr[i]) && (i + 1) < length && newstr[i+1] == '(')
                {
                    newstr.Insert(i + 1, "*");
                    length++;
                }
                else if ( newstr[i] == ')' && (i + 1) < length && char.IsDigit(newstr[i + 1]))
                {
                    newstr.Insert(i + 1, "*");
                    length++;
                }
            }
            equation = newstr.ToString();       
        }

        /// <summary>
        /// 检验负数
        /// </summary>
        private void Negative()
        {
            int k ;
            int count = 0;
            for (int i = 0; i < length; i++)
            {
                if(newstr[i] == '-' && (i + 1) < length  && char.IsDigit(newstr[i + 1]))
                {
                    if(i == 0)
                    {
                        newstr.Insert(i, "(");
                        newstr.Insert(i + 1, "0");
                        length += 2;
                        k = i + 4;
                        while(k < length && newstr[k] != '+' && newstr[k] != '-' && newstr[k] != '*' && newstr[k] != '/' )
                        {
                            count++;
                            k++;
                        }
                        newstr.Insert(k , ")");
                        length += 1;
                        count = 0;
                    }
                }
                else if(newstr[i] == '(' && (i + 1) < length && newstr[i + 1] == '-')
                {
                    newstr.Insert(i + 1, "(");
                    newstr.Insert(i + 2, "0");
                    length += 2;
                    k = i + 5;
                    while (k < length && newstr[k] != ')' && newstr[k] != '+' && newstr[k] != '-' && newstr[k] != '*' && newstr[k] != '/')
                    {
                        count++;
                        k++;
                    }
                    newstr.Insert(k, ")");
                    length += 1;
                    count = 0;
                }
            }
            equation = newstr.ToString();
        }







    }
}
